/**
 *  缩略图实现，将图片(jpg、bmp、png、gif等等)真实的变成想要的大小
 */
package com.sinodata.ns.file;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import org.limp.mine.StringTool;

import java.awt.Image;
import java.awt.image.BufferedImage;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;


/*******************************************************************************
 * 缩略图类（通用） 本java类能将jpg、bmp、png、gif图片文件，进行等比或非等比的大小转换。 具体使用方法
 * compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
 */
public class CompressPicTool {
    private File inputFile; // 输入图路径
    private File outputFile; // 输出图路径
    private int outputWidth = 100; // 默认输出图片宽
    private int outputHeight = 100; // 默认输出图片高
    private boolean proportion = true; // 是否等比缩放标记(默认为等比缩放)

    public CompressPicTool() { // 初始化变量
        outputWidth = 100;
        outputHeight = 100;
    }

    /**
     * 支持的图片类型
     * @param type 图片类型(扩展名)
     * @return boolean
     */
    public static boolean validImg(String type) {
        String tp = StringTool.checkString(type).toLowerCase();

        return "jpg".equals(tp) || "jpeg".equals(tp) || "bmp".equals(tp) ||
        "png".equals(tp) || "gif".equals(tp);
    }

    public void setOutputWidth(int outputWidth) {
        this.outputWidth = outputWidth;
    }

    public void setOutputHeight(int outputHeight) {
        this.outputHeight = outputHeight;
    }

    public void setWidthAndHeight(int width, int height) {
        this.outputWidth = width;
        this.outputHeight = height;
    }

    /*
     * 获得图片大小
     * 传入参数 String path ：图片路径
     */
    public long getPicSize(File file) {
        return file.length();
    }

    /**
     * 图片处理
     * <p>
     *    0 ok,-1 file-not-found,-2 file-is-invalid,-3 unknown exception
     * </p>
     * @return int
     */
    private int compressPic() {
        int rnt = 0;

        //获得源文件
        if (inputFile == null || !inputFile.exists()) {
            rnt = -1;
        } else {
            try {
                Image img = ImageIO.read(inputFile);

                // 判断图片格式是否正确 
                if (img.getWidth(null) == -1) {
                    System.out.println(" can't read, retry!");

                    rnt = -2;
                } else {
                    int newWidth;
                    int newHeight;

                    // 判断是否是等比缩放 
                    if (this.proportion == true) {
                        // 为等比缩放计算输出的图片宽度及高度 
                        double rate1 = (((double) img.getWidth(null)) / (double) outputWidth) +
                            0.1;
                        double rate2 = (((double) img.getHeight(null)) / (double) outputHeight) +
                            0.1;

                        // 根据缩放比率大的进行缩放控制 
                        double rate = (rate1 > rate2) ? rate1 : rate2;
                        newWidth = (int) (((double) img.getWidth(null)) / rate);
                        newHeight = (int) (((double) img.getHeight(null)) / rate);
                    } else {
                        newWidth = outputWidth; // 输出的图片宽度 
                        newHeight = outputHeight; // 输出的图片高度 
                    }

                    BufferedImage tag = new BufferedImage((int) newWidth,
                            (int) newHeight, BufferedImage.TYPE_INT_RGB);

                    /*
                     * Image.SCALE_SMOOTH 的缩略算法 生成缩略图片的平滑度的
                     * 优先级比速度高 生成的图片质量比较好 但速度慢
                     */
                    tag.getGraphics().drawImage(img.getScaledInstance(
                            newWidth, newHeight, Image.SCALE_SMOOTH), 0, 0, null);

                    FileOutputStream out = new FileOutputStream(outputFile);

                    // JPEGImageEncoder可适用于其他图片类型的转换 
                    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
                    encoder.encode(tag);
                    out.close();
                }
            } catch (IOException ex) {
                rnt = -3;
                ex.printStackTrace();
            }
        }

        return rnt;
    }

    /**
     * 图片压缩处理
     * <p>
     *    0 ok,-1 file-not-found,-2 file-is-invalid,-3 unknown exception
     * </p>
     * @param inputFile
     * @param outputFile
     * @param width
     * @param height
     * @param gp 是否等比压缩
     * @return int
     */
    public int compressPic(File inputFile, File outputFile, int width,
        int height, boolean gp) {
        // 输入图路径 
        this.inputFile = inputFile;

        // 输出图路径 
        this.outputFile = outputFile;

        // 设置图片长宽
        setWidthAndHeight(width, height);

        // 是否是等比缩放 标记 
        this.proportion = gp;

        return compressPic();
    }

    // main测试 
    // compressPic(大图片路径,生成小图片路径,大图片文件名,生成小图片文名,生成小图片宽度,生成小图片高度,是否等比缩放(默认为true))
    public static void main(String[] arg) {
        CompressPicTool mypic = new CompressPicTool();

        File inputFile = new File("d:\\IMG_1531.jpg");

        System.out.println("输入的图片大小：" + (mypic.getPicSize(inputFile) / 1024) +
            "KB");

        int count = 0; // 记录全部图片压缩所用时间

        for (int i = 0; i < 1; i++) {
            int start = (int) System.currentTimeMillis(); // 开始时间 

            File outputFile = new File("d:\\test\\r1" + i + ".jpg");

            mypic.compressPic(inputFile, outputFile, 200, 200, true);

            int end = (int) System.currentTimeMillis(); // 结束时间 
            int re = end - start; // 但图片生成处理时间 
            count += re;
            System.out.println("第" + (i + 1) + "张图片压缩处理使用了: " + re + "毫秒");
            System.out.println("输出的图片大小：" +
                (mypic.getPicSize(outputFile) / 1024) + "KB");
        }

        System.out.println("总共用了：" + count + "毫秒");
    }
}
